<?php
#
# DEFINITIONS
#
define('MONKA_VERSION', '10.0a');
define('MONKA_AUTHOR', 'Petko D. (pdp) Petkov');
define('MONKA_AUTHOR_HOMEPAGE', 'http://www.gnucitizen.org/about/pdp');

#
# DEFAULT CONFIG
#
if (!(isset($CONFIG) && is_array($CONFIG))) {
	$CONFIG = array();
}

$CONFIG['error.verbose'] = true;
$CONFIG['session.name'] = 'SESSIONID';
$CONFIG['session.secure'] = true;
$CONFIG['service.internal'] = false;

#
# TEMPORARY SPACE
#
$TEMP = array(
	'found' => false
);

#
# CONFIGURATION
#
require_once dirname(__FILE__).'/__k.config.php';

#
# LIBRARIES
#
require_once dirname(__FILE__).'/__l.Export.php';
require_once dirname(__FILE__).'/__l.Plugin.php';

#
# HELPERS
#
require_once dirname(__FILE__).'/__k.helper.php';

#
# PROCESS USER-FRIENDLY PATHS
#
if (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != '/' && $_SERVER['SCRIPT_NAME'] != $_SERVER['REQUEST_URI']) {
	$TEMP['tokens'] = array_filter(array_map('trim', explode('/', $_SERVER['PATH_INFO'])));

	#
	# PROCESS ACTION
	#
	if (sizeof($TEMP['tokens']) >= 2) {
		#
		# PROCESS PARAMS
		#
		foreach (array_slice($TEMP['tokens'], 2) as $TEMP['value']) {
			$TEMP['split'] = explode('=', $TEMP['value'], 2);

			if (sizeof($TEMP['split']) == 1) {
				#
				# PROCESS SINGLE VALUES
				#
				$PARAMS[] = $TEMP['value'];
			} else {
				#
				# PROCESS KEY=VALUE PAIRS
				#
				$PARAMS[$TEMP['split'][0]] = $TEMP['split'][1];
			}
		}

		$PARAMS['_action'] = $TEMP['tokens'][2];
	}

	#
	# PROCESS SERVICE
	#
	if (sizeof($TEMP['tokens']) >= 1) {
		$PARAMS['_service'] = $TEMP['tokens'][1];
	}
}

#
# CASCADAS
#
if (isset($CONFIG['monka.path.cascadas']) && is_array($CONFIG['monka.path.cascadas'])) {
	rebuild_include_paths($CONFIG['monka.path.cascadas']);
}

#
# REQUIRE LOCAL
#
cascading_require_once('__k.config.php');
cascading_require_once('__k.helper.php');
cascading_require_once('__k.filter.php');
cascading_require_once('__k.action.php');

#
# ERROR HANDLING
#
function monka_error_handler() {
	error('request failed!', 'unexpected error!');
}

set_error_handler('monka_error_handler', E_USER_ERROR);

#
# DISPATCH SERVICE
#
if (isset($PARAMS['_service'])) {
	#
	# LOOK FOR SERVICES IN PATH
	#
	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/_'.$PARAMS['_service'].'.php'))) {
				$TEMP['found'] = true;

				#
				# LOAD CONFIG
				#
				if (is_file($path.'/__k.config.php')) {
					require_once $path.'/__k.config.php';
				}

				#
				# START SESSION
				#
				session_name($CONFIG['session.name']);
				session_start();

				#
				# PATH SERVICE
				#
				require_once $path.'/_'.$PARAMS['_service'].'.php';

				break;
			}
		}
	}

	#
	# LOOK FOR DEFAULT SERVICES
	#
	if (!$TEMP['found']) {
		if (is_file(realpath('_'.$PARAMS['_service'].'.php'))) {
			$TEMP['found'] = true;

			#
			# LOAD CONFIG
			#
			if (is_file('__k.config.php')) {
				require_once '__k.config.php';
			}

			#
			# START SESSION
			#
			session_name($CONFIG['session.name']);
			session_start();

			#
			# LOCAL SERVICE
			#
			require_once '_'.$PARAMS['_service'].'.php';
		} else if (is_file(realpath(dirname(__FILE__).'/_'.$PARAMS['_service'].'.php'))) {
			$TEMP['found'] = true;

			#
			# NO NEED TO LOAD CONFIG
			#

			#
			# START SESSION
			#
			session_name($CONFIG['session.name']);
			session_start();

			#
			# RELATIVE SERVICE
			#
			require_once dirname(__FILE__).'/_'.$PARAMS['_service'].'.php';
		} else {
			#
			# START SESSION
			#
			session_name($CONFIG['session.name']);
			session_start();

			#
			# SERVICE NOT FOUND
			#
			error('service not found!', "service '".(isset($PARAMS['_service'])?stripslashes($PARAMS['_service']):'')."' was not found");
		}
	}

	#
	# SET ERROR HANDLER
	#
	if (function_exists('handler_error')) {
		set_error_handler('handler_error', E_ALL);
	}

	#
	# EXCUTE HANDLER START
	#
	if (function_exists('handler_start')) {
		call_user_func('handler_start');
	}

	#
	#
	#
	if ($CONFIG['service.internal'] && !($_SERVER['REMOTE_ADDR'] == '127.0.0.1' || $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR'])) {
			error('request failed!', 'internal service!');
	}

	#
	# SECURE
	#
	if ($CONFIG['session.secure']) {
		if (!(isset($PARAMS[nonce_name()]) && $PARAMS[nonce_name()] == nonce())) {
			error('request failed!', 'request was forged!');
		}
	}

	#
	# DISPATCH ACTION
	#
	if (isset($PARAMS['_action']) && function_exists('action_'.$PARAMS['_action'])) {
		$php_val = call_user_func('action_'.$PARAMS['_action'], $PARAMS);

		if (isset($php_val)) {
			export($php_val);
		}
	} else {
		if (function_exists('action_default')) {
			$php_val = call_user_func('action_default', $PARAMS);

			if (isset($php_val)) {
				export($php_val);
			}
		} else {
			error('action not found!', "action '".(isset($PARAMS['_action'])?stripslashes($PARAMS['_action']):'')."' was not found");
		}
	}

	#
	# EXCUTE HANDLER FINISH
	#
	if (function_exists('handler_finish')) {
		call_user_func('handler_finish');
	}
} else {
	#
	# SERVICE NOT FOUND
	#
	error('service not found!', "service '".(isset($PARAMS['_service'])?stripslashes($PARAMS['_service']):'')."' was not found");
}

#
# FINISH
#
session_write_close();
